<script setup lang="ts">
import { ref, computed, nextTick, watch } from 'vue';
import { marked } from 'marked';
import {
  ImageIcon,
  FileIcon,
  FileTextIcon,
  FileVideoIcon,
  FileAudioIcon,
  FileArchiveIcon,
  DownloadIcon,
  ExternalLinkIcon,
  EyeIcon,
} from 'lucide-vue-next';
import FileUpload from '@/components/file-upload/FileUpload.vue';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent } from '@/components/ui/card';
import type { UploadResult } from '@/components/file-upload/types';

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  placeholder: '请输入 Markdown 内容...',
  disabled: false,
  showToolbar: true,
  showPreview: true,
  height: 'h-96',
});

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: string];
  'fileUploadSuccess': [result: UploadResult];
}>();

// 配置 marked 选项
marked.setOptions({
  breaks: true,
  gfm: true,
});

// Props
interface Props {
  modelValue?: string;
  placeholder?: string;
  disabled?: boolean;
  showToolbar?: boolean;
  showPreview?: boolean;
  height?: string;
}

// 内部状态
const content = ref(props.modelValue);

// 监听 props 变化
watch(() => props.modelValue, newValue => {
  content.value = newValue;
});

// 监听内容变化
watch(content, newValue => {
  emit('update:modelValue', newValue);
});

// 文件上传相关状态
const showFileUploadDialog = ref(false);
const showImageUploadDialog = ref(false);
const uploadedFiles = ref<UploadResult[]>([]);
const uploadedImages = ref<UploadResult[]>([]);
const previewFile = ref<{ url: string; name: string; type: string } | null>(null);
const showPreviewDialog = ref(false);

const htmlContent = computed(() => {
  return marked(content.value);
});

// 文件类型映射
const fileTypeIcons = {
  image: ImageIcon,
  video: FileVideoIcon,
  audio: FileAudioIcon,
  archive: FileArchiveIcon,
  text: FileTextIcon,
  default: FileIcon,
} as const;

const fileTypeColors = {
  image: 'bg-green-100 text-green-800',
  video: 'bg-purple-100 text-purple-800',
  audio: 'bg-blue-100 text-blue-800',
  archive: 'bg-orange-100 text-orange-800',
  text: 'bg-gray-100 text-gray-800',
  default: 'bg-gray-100 text-gray-800',
} as const;

// 定义文件类型
type FileType = keyof typeof fileTypeColors;

// 获取文件类型
function getFileType(mimeType: string): FileType {
  if (mimeType.startsWith('image/')) {
    return 'image';
  }
  if (mimeType.startsWith('video/')) {
    return 'video';
  }
  if (mimeType.startsWith('audio/')) {
    return 'audio';
  }
  if (mimeType.includes('zip') || mimeType.includes('rar') || mimeType.includes('7z')) {
    return 'archive';
  }
  if (mimeType.startsWith('text/') || mimeType.includes('pdf') || mimeType.includes('document')) {
    return 'text';
  }
  return 'default';
}

// 格式化文件大小
function formatFileSize(bytes: number): string {
  if (bytes === 0) {
    return '0 B';
  }
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${Number.parseFloat((bytes / k ** i).toFixed(1))} ${sizes[i]}`;
}

// 处理文件上传成功
function handleFileUploadSuccess(result: UploadResult) {
  uploadedFiles.value.push(result);
  // 在光标位置插入文件链接
  insertAtCursor(`[${result.originalName}](${result.url})`);
  showFileUploadDialog.value = false;
  emit('fileUploadSuccess', result);
}

// 处理图片上传成功
function handleImageUploadSuccess(result: UploadResult) {
  uploadedImages.value.push(result);
  // 在光标位置插入图片
  insertAtCursor(`![${result.originalName}](${result.url})`);
  showImageUploadDialog.value = false;
  emit('fileUploadSuccess', result);
}

// 在光标位置插入内容
function insertAtCursor(text: string) {
  const textarea = document.querySelector('textarea') as HTMLTextAreaElement;
  if (textarea) {
    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    const currentValue = content.value;

    content.value = currentValue.substring(0, start) + text + currentValue.substring(end);

    // 设置光标位置到插入内容后
    nextTick(() => {
      textarea.focus();
      textarea.setSelectionRange(start + text.length, start + text.length);
    });
  }
}

// 插入 Markdown 语法
function insertMarkdown(syntax: string, placeholder: string = '') {
  const textarea = document.querySelector('textarea') as HTMLTextAreaElement;
  if (textarea) {
    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    const selectedText = content.value.substring(start, end);
    const currentValue = content.value;

    let insertText = '';
    if (selectedText) {
      // 如果有选中文本，用语法包裹
      insertText = syntax.replace('{text}', selectedText);
    } else {
      // 如果没有选中文本，插入语法和占位符
      insertText = syntax.replace('{text}', placeholder);
    }

    content.value = currentValue.substring(0, start) + insertText + currentValue.substring(end);

    // 设置光标位置
    nextTick(() => {
      textarea.focus();
      if (!selectedText) {
        // 如果没有选中文本，将光标放在占位符中间
        const placeholderStart = start + insertText.indexOf(placeholder);
        textarea.setSelectionRange(placeholderStart, placeholderStart + placeholder.length);
      } else {
        // 如果有选中文本，将光标放在插入内容后
        textarea.setSelectionRange(start + insertText.length, start + insertText.length);
      }
    });
  }
}

// 预览文件
function previewFileHandler(file: UploadResult) {
  previewFile.value = {
    url: file.url,
    name: file.originalName,
    type: file.mimeType,
  };
  showPreviewDialog.value = true;
}

// 下载文件
function downloadFile(url: string, filename: string) {
  const link = document.createElement('a');
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

// 在新窗口打开文件
function openFileInNewTab(url: string) {
  window.open(url, '_blank');
}
</script>

<template>
  <div>
    <!-- 工具栏 -->
    <div v-if="showToolbar" class="mb-4 p-3 bg-gray-50 rounded-lg border">
      <div class="flex flex-wrap gap-2 items-center">
        <span class="text-sm font-medium text-gray-700 mr-2">插入:</span>

        <!-- 文本格式按钮 -->
        <Button
          variant="outline"
          size="sm"
          :disabled="disabled"
          @click="insertMarkdown('**{text}**', '粗体文本')"
        >
          粗体
        </Button>
        <Button
          variant="outline"
          size="sm"
          :disabled="disabled"
          @click="insertMarkdown('*{text}*', '斜体文本')"
        >
          斜体
        </Button>
        <Button
          variant="outline"
          size="sm"
          :disabled="disabled"
          @click="insertMarkdown('`{text}`', '代码')"
        >
          代码
        </Button>
        <Button
          variant="outline"
          size="sm"
          :disabled="disabled"
          @click="insertMarkdown('[{text}](url)', '链接文本')"
        >
          链接
        </Button>

        <!-- 分隔线 -->
        <div class="w-px h-6 bg-gray-300 mx-2" />

        <!-- 文件上传按钮 -->
        <Dialog v-model:open="showFileUploadDialog">
          <DialogTrigger as-child>
            <Button variant="outline" size="sm" :disabled="disabled">
              <FileIcon class="w-4 h-4 mr-1" />
              上传文件
            </Button>
          </DialogTrigger>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>上传文件</DialogTitle>
            </DialogHeader>
            <FileUpload
              accept=".pdf,.doc,.docx,.txt,.zip,.rar"
              :multiple="false"
              :auto-upload="true"
              :show-file-list="true"
              :show-progress="true"
              @upload-success="handleFileUploadSuccess"
            />
          </DialogContent>
        </Dialog>

        <!-- 图片上传按钮 -->
        <Dialog v-model:open="showImageUploadDialog">
          <DialogTrigger as-child>
            <Button variant="outline" size="sm" :disabled="disabled">
              <ImageIcon class="w-4 h-4 mr-1" />
              上传图片
            </Button>
          </DialogTrigger>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>上传图片</DialogTitle>
            </DialogHeader>
            <FileUpload
              accept="image/*"
              :multiple="false"
              :auto-upload="true"
              :show-file-list="true"
              :show-progress="true"
              @upload-success="handleImageUploadSuccess"
            />
          </DialogContent>
        </Dialog>
      </div>
    </div>

    <div :class="showPreview ? 'grid grid-cols-2 gap-4' : ''">
      <!-- 编辑区域 -->
      <div>
        <textarea
          v-model="content"
          class="w-full p-4 border rounded-lg resize-none focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono text-sm" :class="[
            height,
            disabled ? 'bg-gray-100 cursor-not-allowed' : '',
          ]"
          :placeholder="placeholder"
          :disabled="disabled"
        />
      </div>

      <!-- 预览区域 -->
      <div v-if="showPreview">
        <div
          class="w-full p-4 border rounded-lg overflow-auto prose max-w-none" :class="[
            height,
          ]"
          v-html="htmlContent"
        />
      </div>
    </div>

    <!-- 已上传文件列表 -->
    <div v-if="(uploadedFiles.length > 0 || uploadedImages.length > 0) && showToolbar" class="mt-6">
      <h3 class="text-lg font-semibold mb-4">
        已上传文件
      </h3>

      <!-- 图片预览 -->
      <div v-if="uploadedImages.length > 0" class="mb-6">
        <h4 class="text-md font-medium mb-3">
          图片
        </h4>
        <div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
          <Card
            v-for="image of uploadedImages"
            :key="image.url"
            class="cursor-pointer hover:shadow-md transition-shadow"
            @click="previewFileHandler(image)"
          >
            <CardContent class="p-2">
              <img
                :src="image.url"
                :alt="image.originalName"
                class="w-full h-24 object-cover rounded mb-2"
              />
              <div class="text-xs text-gray-600 truncate" :title="image.originalName">
                {{ image.originalName }}
              </div>
              <div class="text-xs text-gray-400">
                {{ formatFileSize(image.size) }}
              </div>
            </CardContent>
          </Card>
        </div>
      </div>

      <!-- 文件列表 -->
      <div v-if="uploadedFiles.length > 0">
        <h4 class="text-md font-medium mb-3">
          文件
        </h4>
        <div class="space-y-2">
          <Card
            v-for="file of uploadedFiles"
            :key="file.url"
            class="cursor-pointer hover:shadow-md transition-shadow"
            @click="previewFileHandler(file)"
          >
            <CardContent class="p-3">
              <div class="flex items-center justify-between">
                <div class="flex items-center gap-3">
                  <div class="flex-shrink-0">
                    <component
                      :is="fileTypeIcons[getFileType(file.mimeType)]"
                      class="w-8 h-8 text-gray-500"
                    />
                  </div>
                  <div class="flex-1 min-w-0">
                    <div class="text-sm font-medium text-gray-900 truncate">
                      {{ file.originalName }}
                    </div>
                    <div class="flex items-center gap-2 mt-1">
                      <Badge :class="fileTypeColors[getFileType(file.mimeType)]">
                        {{ getFileType(file.mimeType) }}
                      </Badge>
                      <span class="text-xs text-gray-500">
                        {{ formatFileSize(file.size) }}
                      </span>
                    </div>
                  </div>
                </div>
                <div class="flex items-center gap-1">
                  <Button
                    variant="ghost"
                    size="sm"
                    @click.stop="previewFileHandler(file)"
                  >
                    <EyeIcon class="w-4 h-4" />
                  </Button>
                  <Button
                    variant="ghost"
                    size="sm"
                    @click.stop="downloadFile(file.url, file.originalName)"
                  >
                    <DownloadIcon class="w-4 h-4" />
                  </Button>
                  <Button
                    variant="ghost"
                    size="sm"
                    @click.stop="openFileInNewTab(file.url)"
                  >
                    <ExternalLinkIcon class="w-4 h-4" />
                  </Button>
                </div>
              </div>
            </CardContent>
          </Card>
        </div>
      </div>
    </div>

    <!-- 文件预览对话框 -->
    <Dialog v-model:open="showPreviewDialog">
      <DialogContent class="max-w-4xl max-h-[80vh]">
        <DialogHeader>
          <DialogTitle class="flex items-center gap-2">
            <component
              :is="fileTypeIcons[getFileType(previewFile.type)]"
              v-if="previewFile"
              class="w-5 h-5"
            />
            {{ previewFile?.name }}
          </DialogTitle>
        </DialogHeader>

        <div v-if="previewFile" class="mt-4">
          <!-- 图片预览 -->
          <div v-if="getFileType(previewFile.type) === 'image'" class="text-center">
            <img
              :src="previewFile.url"
              :alt="previewFile.name"
              class="max-w-full max-h-96 object-contain rounded"
            />
          </div>

          <!-- 视频预览 -->
          <div v-else-if="getFileType(previewFile.type) === 'video'" class="text-center">
            <video
              :src="previewFile.url"
              controls
              class="max-w-full max-h-96 rounded"
            >
              您的浏览器不支持视频播放
            </video>
          </div>

          <!-- 音频预览 -->
          <div v-else-if="getFileType(previewFile.type) === 'audio'" class="text-center">
            <audio
              :src="previewFile.url"
              controls
              class="w-full"
            >
              您的浏览器不支持音频播放
            </audio>
          </div>

          <!-- 其他文件类型 -->
          <div v-else class="text-center py-8">
            <component
              :is="fileTypeIcons[getFileType(previewFile.type)]"
              class="w-16 h-16 mx-auto text-gray-400 mb-4"
            />
            <p class="text-gray-600 mb-4">
              此文件类型不支持预览，请下载后查看
            </p>
            <div class="flex gap-2 justify-center">
              <Button @click="downloadFile(previewFile.url, previewFile.name)">
                <DownloadIcon class="w-4 h-4 mr-2" />
                下载文件
              </Button>
              <Button variant="outline" @click="openFileInNewTab(previewFile.url)">
                <ExternalLinkIcon class="w-4 h-4 mr-2" />
                在新窗口打开
              </Button>
            </div>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  </div>
</template>

<style>
@reference "tailwindcss";

.prose h1 {
  @apply text-xl font-bold mb-4;
}
.prose h2 {
  @apply text-xl font-bold mb-3;
}
.prose h3 {
  @apply text-lg font-bold mb-2;
}
.prose p {
  @apply mb-2;
}
.prose code {
  @apply bg-gray-100 px-1 py-0.5 rounded text-sm;
}
.prose pre {
  @apply bg-gray-100 p-2 rounded mb-2 overflow-x-auto;
}
.prose blockquote {
  @apply border-l-4 border-gray-300 pl-4 italic;
}

/* 列表样式 */
.prose ul {
  @apply list-disc list-inside mb-2 space-y-1;
}
.prose ol {
  @apply list-decimal list-inside mb-2 space-y-1;
}
.prose li {
  @apply mb-1;
}
.prose li > ul {
  @apply mt-1 ml-4;
}
.prose li > ol {
  @apply mt-1 ml-4;
}
.prose li > p {
  @apply mb-0;
}

/* 文件链接样式 */
.prose a {
  @apply text-blue-600 hover:text-blue-800 underline;
}
.prose a[href$=".pdf"],
.prose a[href$=".doc"],
.prose a[href$=".docx"],
.prose a[href$=".txt"],
.prose a[href$=".zip"],
.prose a[href$=".rar"] {
  @apply inline-flex items-center gap-1 text-green-600 hover:text-green-800;
}
.prose a[href$=".pdf"]::before,
.prose a[href$=".doc"]::before,
.prose a[href$=".docx"]::before,
.prose a[href$=".txt"]::before,
.prose a[href$=".zip"]::before,
.prose a[href$=".rar"]::before {
  content: "��";
  font-size: 0.8em;
}
</style>
